home *** CD-ROM | disk | FTP | other *** search
- #include "config.h"
-
- #include <sys/types.h>
- #include <stdio.h>
- #include <string.h>
-
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: base64.c,v 1.8 1997/01/18 16:13:20 root Exp root $";
- #endif
-
- #if defined(HTTP) || defined(BROWSER) || defined(TEST)
-
- char *strToBase64 (char *str);
- char *base64ToStr (char *b64);
- static int findBase64 (char c);
- extern void *mallocw (unsigned nb);
-
- #define NULLCHAR ((char *)0)
-
- static char lkBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- static int
- findBase64 (c)
- char c;
- {
- int k;
- for (k = 0; k < 64; k++)
- if (lkBase64[k] == c)
- return k;
- return -1;
- }
-
-
- /* returns a malloc'ed string which is the original string converted to
- base64, or NULLCHAR if cannot malloc, per RFC 1521 */
- char *
- strToBase64 (char *thestr)
- {
- char *b64, *out;
- unsigned char *str = (unsigned char *)thestr;
- int multiple, remainder, len;
- int val;
-
- len = (int) strlen((char *)str);
- multiple = len / 3;
- remainder = len % 3;
-
- out = b64 = mallocw ((unsigned int)(((multiple + 1) * 4) + 1));
- if (out == NULLCHAR)
- return out;
-
- while (multiple--) {
- out[0] = lkBase64[(str[0] >> 2) & 0x3f];
- val = (str[1] >> 4) & 0x0f;
- out[1] = lkBase64[val | ((str[0] << 4) & 0x30)];
- val = (str[1] << 2) & 0x3c;
- out[2] = lkBase64[val | ((str[2] >> 6) & 3)];
- out[3] = lkBase64[str[2] & 0x3f];
-
- out += 4;
- str += 3;
- }
- out[0] = 0;
- if (remainder != 0) {
- out[0] = lkBase64[(str[0] >> 2) & 0x3f];
- out[1] = out[2] = out[3] = '=';
- out[4] = 0;
- if (remainder == 2) {
- val = (str[1] >> 4) & 0x0f;
- out[1] = lkBase64[val | ((str[0] << 4) & 0x30)];
- out[2] = lkBase64[(str[1] << 2) & 0x3c];
- } else {
- out[1] = lkBase64[(str[0] << 4) & 0x30];
- }
- }
- return (b64);
- }
-
-
- /* returns a malloc'ed string which is the original string converted from
- base64, per RFC 1521 - Returns a NULLCHAR if invalid characters
- found or memory cannot be allocated, otherwise the memory must
- STILL be freed. */
- char *
- base64ToStr (char *b64)
- {
- char *str, *out;
- int multiple, remainder = 0, pad = 0, len;
- int val, temp;
-
- len = (int) strlen ((char *)b64);
- multiple = len / 4;
- if (b64[len - 1] == '=')
- pad++;
- if (b64[len - 2] == '=')
- pad++;
- switch (pad) {
- case 2: remainder = 1;
- break;
- case 1: remainder = 2;
- break;
- case 0:
- default: break;
-
- }
- if (pad)
- multiple--;
- out = str = mallocw ((unsigned int)((multiple * 3) + 1));
- if (out == NULLCHAR)
- return out;
-
- while (multiple--) {
- if ((temp = findBase64 (b64[0])) == -1)
- goto error;
- val = (temp << 2); /*lint !e701 */
- if ((temp = findBase64 (b64[1])) == -1)
- goto error;
- out[0] = val | ((temp >> 4) & 3); /*lint !e702 !e734 */
- val = (temp & 0x0f) << 4;
- if ((temp = findBase64 (b64[2])) == -1)
- goto error;
- out[1] = val | ((temp >> 2) & 0x0f); /*lint !e702 !e734 */
- out[2] = (temp << 6); /*lint !e701 !e734 */
- if ((temp = findBase64 (b64[3])) == -1)
- goto error;
- out[2] |= temp; /*lint !e734 */
-
- out += 3;
- b64 += 4;
- }
- out[0] = 0;
- if (remainder != 0) {
- if ((temp = findBase64 (b64[0])) == -1)
- goto error;
- val = (temp << 2); /*lint !e701 */
- if ((temp = findBase64 (b64[1])) == -1)
- goto error;
- out[0] = val | ((temp >> 4) & 3); /*lint !e702 !e734 */
- out[1] = 0;
- if (remainder == 2) {
- if ((temp = findBase64 (b64[1])) == -1)
- goto error;
- val = (temp & 0x0f) << 4;
- if ((temp = findBase64 (b64[2])) == -1)
- goto error;
- out[1] = val | ((temp >> 2) & 0x0f); /*lint !e702 !e734 */
- out[2] = 0;
- }
- }
- return (str);
-
- error:
- str[0] = 0; /*lint !e613 */
- return (str);
- }
-
- #ifdef TEST
- void
- main (argc, argv)
- int argc;
- char *argv[];
- {
- if (argc != 3)
- exit (0);
-
- if (argv[1][0] == 't')
- printf ("Encoding '%s': '%s'\n", argv[2], strToBase64 ((unsigned char *)argv[2]));
- else
- printf ("Decoding '%s': '%s'\n", argv[2], base64ToStr ((unsigned char *)argv[2]));
- }
-
-
- #endif /* TEST */
-
- #endif /* HTTP */
-